﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI;
using Coolite.Ext.Web;
using Newtonsoft.Json.Linq;
using Pap.Data;
using Pap.Web.Modules.Loan.ViewModel;
using Pap.Web.Utils;
using Utils.UIPermission;

namespace Pap.Web.Modules.Loan.Views
{
    /// <summary>
    /// 
    /// </summary>
    public partial class LoanExecutionList : BasePage<LoanExecutionListViewModel>, IPermittedPage
    {
        #region [ Events ]
        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Ext.IsAjaxRequest && !Page.IsPostBack)
            {
                dtExecutionDate.Value = DateTime.Now;
                dtExecutionDate.MaxDate = DateTime.Now;
                dtCheckDate.MaxDate = DateTime.Now;
                RefreshBoards();
            }
        }

        /// <summary>
        /// Handles the Selected event of the CmbBoardTypes control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void CmbBoardTypes_Selected(object sender, AjaxEventArgs e)
        {
            RefreshBoards();
        }

        /// <summary>
        /// Handles the Selected event of the Board control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void Board_Selected(object sender, AjaxEventArgs e)
        {
            RowSelectionModel selectionModel = grvBoards.SelectionModel.Primary as RowSelectionModel;
            if (selectionModel.SelectedRows.Count > 0)
            {
                Guid boardId = new Guid(selectionModel.SelectedRows[0].RecordID);
                storeBoardLoans.DataSource = this.ViewModel.GetBoardLoans(boardId);
                storeBoardLoans.DataBind();
            }

        }

        /// <summary>
        /// Handles the Command event of the gvrLoans control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void gvrLoans_Command(object sender, AjaxEventArgs e)
        {
            RowSelectionModel selectionModel = grvBoardLoan.SelectionModel.Primary as RowSelectionModel;
            string loanID = selectionModel.SelectedRows[0].RecordID;
            if (!loanID.IsNullOrEmpty())
            {
                string jason = e.ExtraParams["grvBoardLoan"];
                JArray jarrChanges = (JArray)JSON.Deserialize(jason);
                string loanNotes = jarrChanges[0]["StatusNotes"].ToString().Trim('"');

                switch (e.ExtraParams["CommandName"])
                {
                    case "AcceptLoan":
                        ShowLoanExecutionWindow(loanID);
                        panelGuarantorError.Hide();
                        panelProcecuted.Hide();
                        panelHasOpenLoan.Hide();
                        break;
                    case "RefuseLoan":
                        RefuseLoanExecution(loanID, loanNotes);
                        break;
                }
            }
        }

        /// <summary>
        /// Handles the Changed event of the txtSSID control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void txtSSID_Changed(object sender, AjaxEventArgs e)
        {
            if (txtGuarantorSSN.Text.Length == 14)
            {
                int year = int.Parse("19" + txtGuarantorSSN.Text.Substring(1, 2));
                int month = int.Parse(txtGuarantorSSN.Text.Substring(3, 2));
                int day = int.Parse(txtGuarantorSSN.Text.Substring(5, 2));
                try
                {
                    new DateTime(year, month, day);
                }
                catch
                {
                    txtGuarantorSSN.MarkInvalid();
                }
                if (!this.ViewModel.ValidateGurantorAvailability(txtGuarantorSSN.Text))
                    txtGuarantorSSN.MarkInvalid();

                if (!this.ViewModel.ValidateGurantorWarning(txtGuarantorSSN.Text))
                    panelGuarantorError.Show();
                else
                    panelGuarantorError.Hide();

                if (!this.ViewModel.ValidateGurantorAvailability(txtGuarantorSSN.Text))
                    panelHasOpenLoan.Show();
                else
                    panelHasOpenLoan.Hide();

                if (this.ViewModel.IsProcecuted(txtGuarantorSSN.Text))
                    panelProcecuted.Show();
                else
                    panelProcecuted.Hide();
            }
        }

        /// <summary>
        /// Handles the Click event of the btnOldDate control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void btnOldDate_Click(object sender, AjaxEventArgs e)
        {
            if (!dtExecutionDate.Disabled)
            {
                try
                {
                    Guid loanID = txtLoanID.Text.ToGuid();
                    string loanNotes = txtNotes.Text;

                    if (loanNotes.IsNullOrEmpty())
                    {
                        Ext.Msg.Configure(new MessageBox.Config
                        {
                            Icon = MessageBox.Icon.ERROR,
                            Title = GetLocalResourceObject("Error").ToString(),
                            Modal = true,
                            Message = GetLocalResourceObject("OldDateNotes").ToString(),
                            Buttons = MessageBox.Button.OK
                        }).Show();
                    }
                    else
                    {
                        this.ViewModel.RequestOldDateExecution(loanID, Convert.ToDateTime(dtExecutionDate.Value), loanNotes);
                        dtExecutionDate.Disabled = true;
                        SetWindowsControls(false);
                        wndLoan.Hide();
                        RefreshBoards();
                    }
                }
                catch
                {
                    Ext.Msg.Configure(new MessageBox.Config
                    {
                        Icon = MessageBox.Icon.ERROR,
                        Title = GetLocalResourceObject("Error").ToString(),
                        Modal = true,
                        Message = GetLocalResourceObject("ErrorMsg").ToString(),
                        Buttons = MessageBox.Button.OK
                    }).Show();
                }
            }
            else
            {
                dtExecutionDate.Disabled = false;
                SetWindowsControls(true);
            }
        }

        /// <summary>
        /// Handles the Clicked event of the btnBack control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="args">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void btnBack_Clicked(object sender, AjaxEventArgs args)
        {
            this.RedirectToPreviousPage();
        }

        #endregion

        #region [ Functions ]

        /// <summary>
        /// Refreshes the boards.
        /// </summary>
        private void RefreshBoards()
        {
            IEnumerable boards;
            switch (cmbBoardTypes.SelectedItem.Value)
            {
                case "Approved":
                    boards = this.ViewModel.GetExecutionBoards();
                    break;
                case "Executed":
                    boards = this.ViewModel.GetExecutedBoards();
                    break;
                case "NotApproved":
                    boards = this.ViewModel.GetWaitingBoards();
                    break;
                default:
                    boards = null;
                    break;
            }

            if (boards != null)
            {
                storeBoards.DataSource = boards;
                storeBoards.DataBind();

                RowSelectionModel selectionModel = grvBoards.SelectionModel.Primary as RowSelectionModel;
                selectionModel.ClearSelections();

                storeBoardLoans.RemoveAll();
            }
        }

        /// <summary>
        /// Refuses the loan execution.
        /// </summary>
        /// <param name="loanID">The loan ID.</param>
        /// <param name="notes">The notes.</param>
        private void RefuseLoanExecution(string loanID, string notes)
        {
            if (notes.IsNullOrEmpty())
            {
                Ext.Msg.Configure(new MessageBox.Config
                {
                    Icon = MessageBox.Icon.ERROR,
                    Title = GetLocalResourceObject("Error").ToString(),
                    Modal = true,
                    Message = GetLocalResourceObject("RefuseNotes").ToString(),
                    Buttons = MessageBox.Button.OK
                }).Show();
            }
            else
            {
                try
                {
                    this.ViewModel.RefuseLoanExecution(loanID.ToGuid(), notes);
                    RefreshBoards();
                }
                catch
                {
                    Ext.Msg.Configure(new MessageBox.Config
                    {
                        Icon = MessageBox.Icon.ERROR,
                        Title = GetLocalResourceObject("Error").ToString(),
                        Modal = true,
                        Message = GetLocalResourceObject("ErrorMsg").ToString(),
                        Buttons = MessageBox.Button.OK
                    }).Show();
                }
            }
        }

        /// <summary>
        /// Shows the loan execution window.
        /// </summary>
        /// <param name="loanID">The loan ID.</param>
        private void ShowLoanExecutionWindow(string loanID)
        {
            txtLoanID.Text = loanID;
            dtExecutionDate.Value = GetFinancialDate();

            Nullable<DateTime> oldDate = this.ViewModel.GetOldDate(loanID.ToGuid());
            if (oldDate != null)
                dtExecutionDate.Value = oldDate;
            ILoanExecution execution = this.ViewModel.GetLoanExecution(loanID.ToGuid());
            if (execution != null)
            {
                txtGuarantor.Text = execution.GuarantorName;
                txtGuarantorSSN.Text = execution.GuarantorSSN;

                txtCheckNumber.Text = execution.CheckNumber;
                dtCheckDate.Value = execution.CheckDate.HasValue ? execution.CheckDate.Value : dtCheckDate.Value;

                ucAttachment.SetImages(execution.LoanExecutionAttachmentsLst.Select(att => att.AttachmentImage));
            }
            else
            {
                txtGuarantor.Reset();
                txtGuarantorSSN.Reset();
                txtCheckNumber.Reset();
                dtCheckDate.Reset();
                ucAttachment.SetImages(new List<IImage>());
            }
            wndLoan.Show();
        }

        /// <summary>
        /// Gets the financial date.
        /// </summary>
        /// <returns></returns>
        private DateTime GetFinancialDate()
        {
            return Pap.Web.Utils.Extentions.ProcessDate;
        }

        /// <summary>
        /// Sets the windows controls.
        /// </summary>
        /// <param name="disabled">if set to <c>true</c> [disabled].</param>
        private void SetWindowsControls(bool disabled)
        {
            txtCheckNumber.Disabled = disabled;
            dtCheckDate.Disabled = disabled;

            txtGuarantor.Disabled = disabled;
            txtGuarantorSSN.Disabled = disabled;

            //txtNotes.Disabled = disabled;
            
            ucAttachment.Disabled = disabled;
            btnSave.Disabled = disabled;
            btnSubmit.Disabled = disabled;
        }

        /// <summary>
        /// Validates the guarantor SSN.
        /// </summary>
        /// <returns></returns>
        private bool ValidateGuarantorSsn()
        {
            if (txtGuarantorSSN.Text.Length == 14)
            {
                int year = int.Parse("19" + txtGuarantorSSN.Text.Substring(1, 2));
                int month = int.Parse(txtGuarantorSSN.Text.Substring(3, 2));
                int day = int.Parse(txtGuarantorSSN.Text.Substring(5, 2));
                if (this.ViewModel.ValidateGurantorAvailability(txtGuarantorSSN.Text) &&
                    this.ViewModel.ValidateGurantorWarning(txtGuarantorSSN.Text) &&
                    !this.ViewModel.IsProcecuted(txtGuarantorSSN.Text))
                {
                    try
                    {
                        new DateTime(year, month, day);
                        return true;
                    }
                    catch
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            else return false;
        }

        #endregion

        #region [ Installments & Contracts ]

        /// <summary>
        /// Handles the Click event of the btnShowInstallments control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void btnShowInstallments_Click(object sender, AjaxEventArgs e)
        {
            //Guid loanID = txtLoanID.Text.ToGuid();
            //string loanNotes = txtNotes.Text;


            //storeLoanInstallments.DataSource = this.ViewModel.GetExecutionInstallments(loanID, Convert.ToDateTime(dtExecutionDate.Value), txtCheckNumber.Text, Convert.ToDateTime(dtCheckDate.Value), txtGuarantor.Text,
            //    txtGuarantorSSN.Text, loanNotes);
            //storeLoanInstallments.DataBind();

            //wndLoanExecutionInstallments.Show();
            Guid loanID = txtLoanID.Text.ToGuid();
            string loanNotes = txtNotes.Text;

            var printInstallments = from installment in this.ViewModel.GetExecutionInstallments(loanID, Convert.ToDateTime(dtExecutionDate.Value), txtCheckNumber.Text, Convert.ToDateTime(dtCheckDate.Value), txtGuarantor.Text,
               txtGuarantorSSN.Text, loanNotes)
                                    select new
                                    {
                                        InstallmentDate = installment.InstallmentDate,
                                        OriginalInstallmentAmount = installment.OriginalInstallmentAmount,
                                        InterestInstallmentAmount = installment.InterestInstallmentAmount,
                                        TotalInstallmentAmount = installment.TotalInstallmentAmount
                                    };

            Session.Add("InstallmentsList", printInstallments);
            wndInstallmentPrint.LoadContent("~/Loan.route/InstallmentGridPrint");
            wndInstallmentPrint.Show();
        }

        /// <summary>
        /// Handles the Click event of the btnShowContract control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void btnShowContract_Click(object sender, AjaxEventArgs e)
        {
            Guid loanID = txtLoanID.Text.ToGuid();
            var lastExecution = this.ViewModel.GetLoanExecution(loanID);
            // exeption if there's no execution saved => send loanID and recreate the execution
            if (lastExecution != null)
            {
                wndInstallmentPrint.LoadContent("~/Loan.route/PrintContract?ExecutionID=" + lastExecution.LoanExecutionID);
                wndInstallmentPrint.Show();
            }
            else
            {
                wndInstallmentPrint.LoadContent(string.Format("~/Loan.route/PrintContract?LoanID={0}&executionDate={1}",
                    loanID, Convert.ToDateTime(dtExecutionDate.Value).Date.ToShortDateString()));
                wndInstallmentPrint.Show();
            }

        }

        /// <summary>
        /// Handles the Closed event of the wndInstallmentPrint control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void wndInstallmentPrint_Closed(object sender, AjaxEventArgs e)
        {
            if (Session["InstallmentsList"] != null)
            {
                Session.Remove("InstallmentsList");
            }
        }

        #endregion

        #region [ Buttons ]

        /// <summary>
        /// Handles the Clicked event of the BtnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void BtnSave_Clicked(object sender, AjaxEventArgs e)
        {
            try
            {
                if (ValidateGuarantorSsn())
                {
                    Guid loanID = txtLoanID.Text.ToGuid();
                    string loanNotes = txtNotes.Text;

                    this.ViewModel.SaveLoanExecution(loanID, Convert.ToDateTime(dtExecutionDate.Value), txtCheckNumber.Text, Convert.ToDateTime(dtCheckDate.Value), txtGuarantor.Text,
                        txtGuarantorSSN.Text, loanNotes, ucAttachment.GetInsertedIDs(), ucAttachment.GetDeletedIDs());
                    wndLoan.Hide();
                }
                else
                {
                    txtGuarantorSSN.MarkInvalid();
                }
            }
            catch
            {
                Ext.Msg.Configure(new MessageBox.Config
                {
                    Icon = MessageBox.Icon.ERROR,
                    Title = GetLocalResourceObject("Error").ToString(),
                    Modal = true,
                    Message = GetLocalResourceObject("ErrorMsg").ToString(),
                    Buttons = MessageBox.Button.OK
                }).Show();
            }
        }

        /// <summary>
        /// Handles the Clicked event of the BtnSubmit control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void BtnSubmit_Clicked(object sender, AjaxEventArgs e)
        {
            try
            {
                if (ValidateGuarantorSsn())
                {
                    Guid loanID = txtLoanID.Text.ToGuid();
                    string loanNotes = txtNotes.Text;
                    if (this.ViewModel.HasEnoughMoney(loanID))
                    {
                        if (this.ViewModel.AcceptLoanExecution(loanID, Convert.ToDateTime(dtExecutionDate.Value), txtCheckNumber.Text,
                            Convert.ToDateTime(dtCheckDate.Value), txtGuarantor.Text, txtGuarantorSSN.Text,
                            loanNotes, ucAttachment.GetInsertedIDs(), ucAttachment.GetDeletedIDs()))
                        {
                            wndLoan.Hide();
                            RefreshBoards();
                        }
                        else
                        {
                            Ext.Msg.Configure(new MessageBox.Config
                            {
                                Icon = MessageBox.Icon.ERROR,
                                Title = GetLocalResourceObject("Error").ToString(),
                                Modal = true,
                                Message = GetLocalResourceObject("GurantorNotValid").ToString(),
                                Buttons = MessageBox.Button.OK
                            }).Show();
                        }
                    }
                    else
                    {
                        Ext.Msg.Configure(new MessageBox.Config
                        {
                            Icon = MessageBox.Icon.ERROR,
                            Title = GetLocalResourceObject("Error").ToString(),
                            Modal = true,
                            Message = GetLocalResourceObject("ErrorMsgBalance").ToString(),
                            Buttons = MessageBox.Button.OK
                        }).Show();
                    }

                }
                else
                {
                    txtGuarantorSSN.MarkInvalid();
                }
            }
            catch
            {
                Ext.Msg.Configure(new MessageBox.Config
                {
                    Icon = MessageBox.Icon.ERROR,
                    Title = GetLocalResourceObject("Error").ToString(),
                    Modal = true,
                    Message = GetLocalResourceObject("ErrorMsg").ToString(),
                    Buttons = MessageBox.Button.OK
                }).Show();
            }
        }

        /// <summary>
        /// Handles the Clicked event of the BtnCancle control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void BtnCancle_Clicked(object sender, AjaxEventArgs e)
        {
            dtExecutionDate.Disabled = true;
            SetWindowsControls(false);
            wndLoan.Hide();
        }

        #endregion

        #region [ IPermittedPage Members ]

        /// <summary>
        /// Gets the name of the permission.
        /// </summary>
        /// <value>
        /// The name of the permission.
        /// </value>
        public string PermissionName
        {
            get { return Permissions.ReviewerWaitingList.ToString(); }
        }

        #endregion
    }
}
